package com.sena.crawler.rundata.strategy;

import com.sena.crawler.exception.SenaCrawlerException;
import com.sena.crawler.domian.Link;
import com.sena.crawler.rundata.RunData;
import com.sena.crawler.util.UrlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * lcoal run data
 *
 * @author seven-12-14 11:42:23
 */
public class LocalRunData extends RunData {
    private static Logger logger = LoggerFactory.getLogger(LocalRunData.class);

    // url
    private volatile LinkedBlockingQueue<Link> unVisitedUrlQueue = new LinkedBlockingQueue<Link>();     // 待采集URL池


    private volatile LinkedBlockingQueue<Link> visitedUrlSet = new LinkedBlockingQueue<Link>();        // 已采集URL池


    /**
     * url add
     *
     * @param link
     */
    @Override
    public boolean addUrl(Link link) {
        if (!UrlUtil.isUrl(link.getLink())) {
            logger.debug(">>>>>>>>>>> sena-crawler addUrl fail, link not valid: {}", link.getLink());
            return false; // check URL格式
        }
        if (visitedUrlSet.contains(link)) {
            logger.debug(">>>>>>>>>>> sena-crawler addUrl fail, link repeat: {}", link.getLink());
            return false; // check 未访问过
        }
        if (unVisitedUrlQueue.contains(link)) {
            logger.debug(">>>>>>>>>>> sena-crawler addUrl fail, link visited: {}", link.getLink());
            return false; // check 未记录过
        }
        unVisitedUrlQueue.add(link);
        logger.info(">>>>>>>>>>> sena-crawler addUrl success, link: {}", link.getLink());
        return true;
    }

    @Override
    public boolean isFind(Link link) {
        if (!UrlUtil.isUrl(link.getLink())) {
            logger.debug(">>>>>>>>>>> sena-crawler find fail, link not valid: {}", link.getLink());
            return false; // check URL格式
        }
        if (visitedUrlSet.contains(link)) {
            logger.debug(">>>>>>>>>>> sena-crawler find fail, link repeat: {}", link.getLink());
            return false; // check 未访问过
        }
        if (unVisitedUrlQueue.contains(link)) {
            logger.debug(">>>>>>>>>>> sena-crawler find fail, link visited: {}", link.getLink());
            return false; // check 未记录过
        }
        logger.info(">>>>>>>>>>> sena-crawler find success, link: {}", link.getLink());
        return true;
    }



    /**
     * url take
     *
     * @return String
     * @throws InterruptedException
     */
    @Override
    public Link getUrl() {
        Link link = null;
        try {
            link = unVisitedUrlQueue.take();
        } catch (InterruptedException e) {
            throw new SenaCrawlerException("》》》》》》》》》》》》未获取到连接打断线程.");
        }
        if (link != null) {
            visitedUrlSet.add(link);
        }
        return link;
    }

    @Override
    public Long getUrlNum() {
        return (long) unVisitedUrlQueue.size();
    }


}
